package cn.fintecher.pangolin.service.report.config;

import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.model.response.SystemLogModel;
import cn.fintecher.pangolin.common.utils.BeanUtils;
import cn.fintecher.pangolin.common.utils.Snowflake;
import cn.fintecher.pangolin.common.web.SystemLogConfig;
import cn.fintecher.pangolin.entity.elastic.SystemLog;
import cn.fintecher.pangolin.service.report.elastic.SystemLogElastic;
import cn.fintecher.pangolin.service.report.service.BaseService;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @Author: huyanmin
 * @Description: 系统日志
 * @Date 2018/6/29
 */
@Aspect
@Component
public class SystemLogAop {

    private final static String AFTER = "after";
    private final static String EXCEPTION = "exception";
    private final Logger log = LoggerFactory.getLogger(SystemLogAop.class);
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Autowired
    private BaseService baseService;

    @Autowired
    private SystemLogConfig systemLogConfig;

    @Autowired
    private SystemLogElastic systemLogElastic;

    private Snowflake snowflake = new Snowflake((int) Thread.currentThread().getId() % 1024);

    // 切入点*Controller
    @Pointcut("execution(public * cn.fintecher.pangolin.*.*.web.*Controller.*(..))")
    public void systemLogAop() {
    }

    @Before("systemLogAop()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
    }

    @After("systemLogAop()")
    public void doAfter(JoinPoint joinPoint) throws Throwable {
        SystemLogModel systemLogModel = systemLogConfig.saveSystemLogsBlock(joinPoint, AFTER, null, startTime);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String tokenStr = request.getHeader("X-UserToken");
        if (StringUtils.isNotBlank(tokenStr)) {
            UserModel userModel = baseService.getUserByToken(tokenStr);
            if (Objects.nonNull(systemLogModel)) {
                SystemLog systemLog = new SystemLog();
                BeanUtils.copyProperties(systemLogModel, systemLog);
                systemLog.setOperator(userModel.getUsername());
                systemLog.setOperatorName(userModel.getRealName());
                systemLog.setId(String.valueOf(snowflake.next()));
                systemLogElastic.save(systemLog);
            }
        }
    }

    /**
     * 异常通知 用于拦截记录异常日志
     *
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "systemLogAop()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
        systemLogConfig.saveSystemLogsBlock(joinPoint, EXCEPTION, e, startTime);
    }
}
